home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 11 - 1995 / 11.04 Apr 95 / TreeAppƒ / Eric's C++ Libraries / Interface Classes / CPPWindow.cp < prev    next >
Encoding:
Text File  |  1996-04-04  |  23.7 KB  |  881 lines  |  [TEXT/KAHL]

  1. /***************************************************** IMPLEMENTATION
  2.     DATE:    9/20/93
  3.     AUTHOR: Eric R. Rosé
  4.  
  5.     CLASS:  CPPWindow
  6.     
  7.     SUPERCLASS: CPPObjectList
  8.     
  9.         This C++ class manages a Macintosh window; it is subclassed
  10.         from an object list so that it can keep track of all of the
  11.         objects within the window
  12.     
  13. ********************************************************************/
  14.  
  15. #include <CPPWindow.h>
  16. #include <math.h>
  17. #include <MathTools.h>
  18. #include <CPPWindowManager.h>
  19. #include <CPPVisualObject.h>
  20. #include <Commands.h>
  21.  
  22.  
  23. /*-----------------------------------------------------------------*/
  24. /*--------------------------- GLOBALS -----------------------------*/
  25. /*-----------------------------------------------------------------*/
  26.  
  27.     CPPWindow    *gTheModalWindow;
  28.     pascal Boolean ModalFilterProc (DialogPtr theDlg,
  29.                                     EventRecord *theEvent,
  30.                                     short *itemHit );
  31.     void DoStdOKButton (CPPWindow *theWindow);
  32.     void DoStdCancelButton (CPPWindow *theWindow);
  33.  
  34. /*-----------------------------------------------------------------*/
  35. /*------------------------ PUBLIC METHODS -------------------------*/
  36. /*-----------------------------------------------------------------*/
  37.  
  38.     void DoStdCancelButton (CPPWindow *theWindow)
  39.     {
  40.         if (theWindow)
  41.           theWindow->EndModalWindow (FALSE);
  42.     }
  43.  
  44. /*-----------------------------------------------------------------*/
  45.  
  46.     void DoStdOKButton (CPPWindow *theWindow)
  47.     {
  48.         if (theWindow)
  49.           theWindow->EndModalWindow (TRUE);
  50.     }
  51.  
  52. /*-----------------------------------------------------------------*/
  53.  
  54.     CPPWindow::CPPWindow (CPPWindowManager *theManager,
  55.                           Rect *bounds, Str255 title, Boolean isVisible,
  56.                           short windowKind, Boolean hasGoAway, short refCon,
  57.                           Boolean isModal, Boolean isColor, 
  58.                           short windowFont, short windowSize)
  59.     /* create a window based on the passed in parameters */
  60.     {
  61.         if (isColor)
  62.           this->theWindow = NewCWindow(NULL, bounds, title, isVisible, 
  63.                                         windowKind, (WindowPtr)-1,
  64.                                         hasGoAway, refCon);
  65.         else
  66.           this->theWindow = NewWindow(NULL, bounds, title, isVisible, 
  67.                                         windowKind, (WindowPtr)-1,
  68.                                         hasGoAway, refCon);
  69.           
  70.         if (this->theWindow)
  71.           MakeCPPWindow (theManager, windowFont, windowSize);
  72.         else
  73.           this->WisVisible = this->WisActive = FALSE;
  74.         
  75.         this->isCWindow = isColor;
  76.         this->isModalWindow = isModal;
  77.         this->modalResult = FALSE;
  78.     }
  79.     
  80. /*-----------------------------------------------------------------*/
  81.  
  82.     CPPWindow::CPPWindow (CPPWindowManager *theManager, short ResID,
  83.                           Boolean isModal, Boolean isColor, 
  84.                           short windowFont, short windowSize)
  85.     /* get a window based on an existing resource template */
  86.     {
  87.         
  88.           if (isColor)
  89.             this->theWindow = GetNewCWindow(ResID, NULL, (WindowPtr)-1);
  90.         else
  91.             this->theWindow = GetNewWindow(ResID, NULL, (WindowPtr)-1);
  92.           
  93.           if (this->theWindow)
  94.             MakeCPPWindow (theManager, windowFont, windowSize);
  95.         else
  96.           this->WisVisible = this->WisActive = FALSE;
  97.           
  98.         this->isCWindow = isColor;
  99.         this->isModalWindow = isModal;
  100.     }
  101.     
  102. /*-----------------------------------------------------------------*/
  103.     
  104.     CPPWindow::~CPPWindow (void)
  105.     {
  106.         CPPVisualObject    *TempObject = NULL;
  107.  
  108.         // first, hide our window; this will take care of
  109.         // updates in the window list
  110.         this->Close();
  111.         
  112.         // tell the windowmanager it doesn't have to worry about us
  113.         if (this->ourManager)
  114.           this->ourManager->StopManagingWindow(this);
  115.         
  116.         // dispose of all the objects which we contain
  117.         DeleteItems(TRUE);
  118.         
  119.         // finally, dispose of our own data
  120.         if (this->theWindow)
  121.           DisposeWindow(this->theWindow);
  122.     }
  123.             
  124. /*-----------------------------------------------------------------*/
  125.  
  126.     void    CPPWindow::Close (void)
  127.     /* perform a close operation by simply hiding the window */
  128.     {
  129.         if (this->theWindow && ((WindowPeek)this->theWindow)->goAwayFlag)
  130.           this->Show(FALSE);
  131.     }
  132.  
  133. /*-----------------------------------------------------------------*/
  134.  
  135.     void    CPPWindow::Open (void)
  136.     /* perform a close operation by simply showing a hidden window */
  137.     {
  138.         this->Show(TRUE);
  139.     }
  140.  
  141. /*-----------------------------------------------------------------*/
  142.  
  143.     Boolean    CPPWindow::Member (char *className)
  144.     {
  145.         if (strcmp(className, CPPWindow::ClassName()) == 0)
  146.           return TRUE;
  147.         else
  148.           return CPPObjectList::Member(className);
  149.     }
  150.  
  151. /*-----------------------------------------------------------------*/
  152.  
  153.     char    *CPPWindow::ClassName (void)
  154.     {
  155.         return "CPPWindow";
  156.     }
  157.             
  158. /*-----------------------------------------------------------------*/
  159.  
  160.     void    CPPWindow::EndModalWindow (Boolean endResult)
  161.     /* tell the modal window to dismiss itself; return the specified */
  162.     /* value as a result */
  163.     {
  164.         this->modalResult = endResult;
  165.         this->modalDone = TRUE;
  166.     }
  167.  
  168. /*-----------------------------------------------------------------*/
  169.  
  170.     void    CPPWindow::DoModalWindow (void)
  171.     /* treat the window as if it were a modal window */
  172.     {
  173.         EventRecord        theEvent;
  174.         CPPWindow        *theWindowObject;
  175.         short            eventMask;
  176.     
  177.         // assume the user will cancel
  178.         this->modalResult = FALSE;
  179.         
  180.         // set up the event mask to only accept modal dialog events
  181.         eventMask = mDownMask + mUpMask + keyDownMask + keyUpMask +
  182.                     autoKeyMask + updateMask + activMask + networkMask;
  183.         
  184.           // set the modal window completion variable
  185.           this->modalDone = FALSE;
  186.  
  187.         while (!this->modalDone)
  188.           {
  189.               if (WaitNextEvent(eventMask, &theEvent, 0, NULL))
  190.               this->Do(&theEvent);
  191.             else    
  192.               this->DoIdle();
  193.           }
  194.     }
  195.  
  196. /*-----------------------------------------------------------------*/
  197.  
  198.     void    CPPWindow::SetMinMaxSize (short minWidth, short minHeight,
  199.                                        short maxWidth, short maxHeight)
  200.     {
  201.         this->minWidth = minWidth;
  202.         this->minHeight = minHeight;
  203.         this->maxWidth = maxWidth;
  204.         this->maxHeight = maxHeight;
  205.         
  206.         // let the window manager maintain the data it needs
  207.         // for zoomable windows;
  208.           switch (GetWVariant(this->theWindow)) {
  209.               case zoomNoGrow :
  210.               case zoomDocProc :
  211.                 SetZoomedOutSize (maxWidth, maxHeight);
  212.                   break;
  213.           }
  214.     }
  215.  
  216. /*-----------------------------------------------------------------*/
  217.  
  218.     void    CPPWindow::SetZoomedOutSize (short maxWidth, short maxHeight)
  219.     {
  220.         WStateData    **hWSD;
  221.         Rect        zRect;
  222.         
  223.         // set the 'zoomed out' size of the window to the maximum size
  224.         if (theWindow)
  225.           {
  226.               hWSD = (WStateData **)((WindowPeek)theWindow)->dataHandle;
  227.               zRect = (**hWSD).stdState;
  228.               zRect.bottom = Min (zRect.top + maxHeight, zRect.bottom);
  229.               zRect.right = Min (zRect.left + maxWidth, zRect.right);
  230.               (**hWSD).stdState = zRect;
  231.               this->maxWidth = (zRect.right - zRect.left);
  232.               this->maxHeight = (zRect.bottom - zRect.top);
  233.           }
  234.     }
  235.  
  236. /*-----------------------------------------------------------------*/
  237.  
  238.     Boolean    CPPWindow::DoCommand (short commandID)
  239.     /* the default method sends the command to the target of the */
  240.     /* window. */
  241.     /* SUBCLASS SHOULD OVERRIDE */
  242.     {
  243.         CPPVisualObject *theTarget = GetTarget();
  244.         
  245.         if (theTarget)
  246.           return theTarget->DoCommand(commandID);
  247.         else
  248.           return FALSE;
  249.     }
  250.  
  251. /*-----------------------------------------------------------------*/
  252.  
  253.     WindowPtr    CPPWindow::GetWindow (void)
  254.     {
  255.         return this->theWindow;
  256.     }
  257.  
  258. /*-----------------------------------------------------------------*/
  259.  
  260.     void    CPPWindow::Update (EventRecord *theEvent)
  261.     {
  262.         WindowPtr    uWindow = (WindowPtr)theEvent->message;
  263.         GrafPtr        savePort;
  264.         
  265.         if (uWindow == this->theWindow)
  266.           {
  267.               // prepare the window to be drawn into
  268.               BeginUpdate (this->theWindow);
  269.               GetPort (&savePort);
  270.               SetPort (this->theWindow);
  271.               
  272.               // call the user's draw routine
  273.               this->DoUserUpdate();
  274.               
  275.               // draw the grow icon if necessary
  276.               switch (GetWVariant(this->theWindow)) {
  277.                   case documentProc :
  278.                   case zoomDocProc :
  279.                       DrawGrowIcon(this->theWindow);
  280.                       break;
  281.               }
  282.               
  283.               // restore the drawing environment
  284.               SetPort (savePort);
  285.               EndUpdate (this->theWindow);
  286.           }
  287.     }
  288.     
  289. /*-----------------------------------------------------------------*/
  290.  
  291.     void    CPPWindow::Show (Boolean doShowWindow)
  292.     /* make the window visible or invisible */
  293.     {
  294.         if (this->theWindow)
  295.           {
  296.             if (doShowWindow)
  297.               {
  298.                 ShowWindow (this->theWindow);
  299.                 SelectWindow (this->theWindow);
  300.                 this->ourManager->ActivateWindowObject (this);
  301.               }
  302.             else
  303.               {
  304.                   HideWindow(this->theWindow);
  305.                 this->ourManager->DeactivateWindowObject (this);
  306.                 }
  307.             
  308.             this->WisVisible = doShowWindow;
  309.           }
  310.     }
  311.             
  312. /*-----------------------------------------------------------------*/
  313.  
  314.     void    CPPWindow::RefreshItemStates()
  315.     /* this routine is called whenever an event occurs so that */
  316.     /* the window can check to see if any of the objects in it */
  317.     /* should be enabled/disabled, etc.  For example, if a button */
  318.     /* should only be active when certain conditions are true, */
  319.     /* you could use this routine to activate/deactivate it */
  320.     /* SUBCLASS SHOULD OVERRIDE */
  321.     {
  322.     
  323.     }
  324.  
  325. /*-----------------------------------------------------------------*/
  326.  
  327.     Boolean    CPPWindow::Do (EventRecord *theEvent)
  328.     /* handle the passed event; return TRUE if you handle it, */
  329.     /* FALSE if you dont */
  330.     {
  331.         GrafPtr    savePort;
  332.         Boolean    result = FALSE;
  333.         WindowPtr    EventWindow;
  334.                 
  335.         if (!theWindow) return FALSE;
  336.         
  337.         // check to see if the event happened in our window
  338.         switch (theEvent->what) {
  339.             case updateEvt :
  340.             case activateEvt :
  341.                 EventWindow = (WindowPtr)theEvent->message;
  342.                 break;
  343.             case keyDown :
  344.             case autoKey :
  345.                 EventWindow = FrontWindow();
  346.                 break;
  347.             default :
  348.                 FindWindow (theEvent->where, &EventWindow);
  349.                 break;
  350.         } 
  351.         
  352.         if (this->theWindow != EventWindow)
  353.           return FALSE;
  354.         
  355.         // now that we know the event happened in our window,
  356.         // handle it
  357.         GetPort(&savePort);
  358.         SetPort(this->theWindow);
  359.     
  360.         switch (theEvent->what) {
  361.             case nullEvent : 
  362.                 if (this->WisActive)
  363.                     {
  364.                       DoUserIdle ();
  365.                       result = TRUE;
  366.                     }
  367.                   break;
  368.             case mouseDown :
  369.                 result = this->DoClick(theEvent);
  370.                 break;
  371.             case keyDown :
  372.             case autoKey :
  373.                 result = this->DoUserKey (theEvent);
  374.                 break;
  375.             case updateEvt:
  376.                 this->Update(theEvent);
  377.                 result = TRUE;
  378.                 break;
  379.             case activateEvt :
  380.                 if (ODD(theEvent->modifiers))
  381.                   this->ourManager->ActivateWindowObject(this);
  382.                 else
  383.                   this->ourManager->DeactivateWindowObject(this);
  384.                 result = TRUE;
  385.                 break;
  386.         }
  387.         
  388.         RefreshItemStates();
  389.         
  390.         SetPort(savePort);
  391.         return result;
  392.     }
  393.  
  394. /*-----------------------------------------------------------------*/
  395.  
  396.     Boolean    CPPWindow::DoClick (EventRecord *theEvent)
  397.     /* react to a click in the object's window by bringing it */
  398.     /* forward (if necessary) and performing the appropriate action */
  399.     /* return TRUE if the click was in our window, FALSE otherwise */
  400.     {
  401.         short    part;
  402.         WindowPtr    hitWindow;
  403.  
  404.         part = FindWindow(theEvent->where, &hitWindow);
  405.         if (hitWindow == this->theWindow)
  406.           {
  407.               if (!this->WisActive)
  408.                 SelectWindow(this->theWindow);
  409.  
  410.               switch (part) {
  411.                   case inDrag     :
  412.                       DoDragClick (theEvent);
  413.                       break;
  414.                   case inGrow        :
  415.                       DoGrowClick (theEvent);
  416.                       break;
  417.                   case inZoomIn    :
  418.                       DoZoomClick (theEvent, part);
  419.                       break;
  420.                   case inZoomOut    :
  421.                       DoZoomClick (theEvent, part);
  422.                       break;
  423.                   case inGoAway    :
  424.                     DoGoAwayClick (theEvent);
  425.                     break;
  426.                   case inContent    :
  427.                     DoContentClick (theEvent);
  428.                     break;
  429.                 default :
  430.                     return FALSE;
  431.                     break;
  432.               }
  433.               return TRUE;
  434.           }
  435.           
  436.         return FALSE;
  437.     }
  438.  
  439. /*-----------------------------------------------------------------*/
  440.  
  441.     void    CPPWindow::DoIdle (void)
  442.     {
  443.         DoUserIdle ();
  444.     }
  445.  
  446. /*-----------------------------------------------------------------*/
  447.  
  448.     Boolean    CPPWindow::MakePreviousTarget (void)
  449.     /* make the 'targetable' and visible object preceeding the */
  450.     /* current one into the target for the window; return TRUE if */
  451.     /* the target changes */
  452.     {
  453.         CPPVisualObject    *oldTarget = this->currentTarget, 
  454.                         *newTarget = NULL,
  455.                         *tempObject = NULL;
  456.         long            itemsToCheck = GetNumItems(),
  457.                         itemsInList = itemsToCheck,
  458.                         current = FindIndex(currentTarget);
  459.         
  460.         // proceed through the list from the current element,
  461.         // looking for the next one which can be made the target            
  462.         while (itemsToCheck)
  463.           {
  464.               current--;
  465.               if (!current)
  466.                 current = itemsInList;
  467.               tempObject = (CPPVisualObject *)((*this)[current]);
  468.               if (tempObject && tempObject->IsVisible() && 
  469.                   tempObject->CanBeMadeTarget())
  470.                 {
  471.                     newTarget = tempObject;
  472.                     break;
  473.                 }
  474.               itemsToCheck--;
  475.           }
  476.         
  477.         // if there is another object targetable, target it
  478.         if ((newTarget) && (newTarget != oldTarget))
  479.           {
  480.             MakeTarget(newTarget);
  481.             return TRUE;
  482.           }
  483.         else
  484.           return FALSE;
  485.     }
  486.  
  487. /*-----------------------------------------------------------------*/
  488.  
  489.     Boolean    CPPWindow::MakeNextTarget ()
  490.     /* make the next 'targetable' and visible object into the target */
  491.     /* for the window; return TRUE if the target changed */
  492.     {
  493.         CPPVisualObject    *oldTarget = this->currentTarget, 
  494.                         *newTarget = NULL,
  495.                         *tempObject = NULL;
  496.         long            itemsToCheck = GetNumItems(),
  497.                         itemsInList = itemsToCheck,
  498.                         current = FindIndex(currentTarget);
  499.         
  500.         // proceed through the list from the current element,
  501.         // looking for the next one which can be made the target            
  502.         while (itemsToCheck)
  503.           {
  504.               current = ((current + 1) % (itemsInList+1));
  505.               current += (current) ? 0 : 1;
  506.               tempObject = (CPPVisualObject *)((*this)[current]);
  507.               if (tempObject && tempObject->IsVisible() && 
  508.                   tempObject->CanBeMadeTarget())
  509.                 {
  510.                     newTarget = tempObject;
  511.                     break;
  512.                 }
  513.               itemsToCheck--;
  514.           }
  515.         
  516.         // if there is another object targetable, target it
  517.         if ((newTarget) && (newTarget != oldTarget))
  518.           {
  519.             MakeTarget(newTarget);
  520.             return TRUE;
  521.           }
  522.         else
  523.           return FALSE;
  524.     }
  525.  
  526. /*-----------------------------------------------------------------*/
  527.  
  528.     CPPVisualObject     *CPPWindow::GetTarget (void)
  529.     /* return the current target in the window */
  530.     {
  531.         return this->currentTarget;
  532.     }
  533.  
  534. /*-----------------------------------------------------------------*/
  535.  
  536.     void    CPPWindow::MakeTarget (CPPVisualObject *theObject)
  537.     /* The target is the object which should receive key events. */
  538.     /* call this routine to change the target object in the window */
  539.     /* if 'theObject' = NULL, assume the user wants to deactivate */
  540.     /* the current target without assigning another */
  541.     {
  542.         if (theObject == NULL)
  543.           {
  544.               if (this->currentTarget)
  545.                 this->currentTarget->TargetHilite(FALSE);
  546.               this->currentTarget = NULL;
  547.           }
  548.         else
  549.         if (FindIndex(theObject))
  550.           {
  551.               if ((theObject != this->currentTarget) && 
  552.                   theObject->CanBeMadeTarget() && theObject->IsVisible())
  553.                 {
  554.                 if (this->currentTarget)
  555.                   this->currentTarget->TargetHilite (FALSE);
  556.                 this->currentTarget = theObject;
  557.                 this->currentTarget->TargetHilite (TRUE);
  558.                 }
  559.           }
  560.     }
  561.  
  562. /*-----------------------------------------------------------------*/
  563.  
  564.     Boolean CPPWindow::IsColorWindow (void)
  565.     /* return TRUE if this is a color window */
  566.     {
  567.         return this->isCWindow;
  568.     }
  569.  
  570. /*-----------------------------------------------------------------*/
  571.  
  572.     Boolean CPPWindow::IsModalWindow (void)
  573.     /* return TRUE if this is a modal or movable modal window */
  574.     {
  575.         return this->isModalWindow;
  576.     }
  577.  
  578. /*-----------------------------------------------------------------*/
  579.  
  580.     Boolean    CPPWindow::WindowVisible (void)
  581.     /* return whether or not the window is visible */
  582.     {
  583.         return this->WisVisible;
  584.     }
  585.  
  586. /*-----------------------------------------------------------------*/
  587.  
  588.     Boolean    CPPWindow::WindowActive (void)
  589.     /* return whether or not the window is active */
  590.     {
  591.         return this->WisActive;
  592.     }
  593.  
  594. /*-----------------------------------------------------------------*/
  595.  
  596.     void    CPPWindow::StartManagingObject (CPPVisualObject *theObject)
  597.     /* add a visual object to the list of objects we know about */
  598.     {
  599.         if (theObject)
  600.           this->AppendItem (theObject);
  601.     }
  602.  
  603. /*-----------------------------------------------------------------*/
  604.  
  605.     void    CPPWindow::StopManagingObject (CPPVisualObject *theObject)
  606.     /* remove a visual object from the list of objects we know about */
  607.     {
  608.         DeleteItem(theObject, FALSE);
  609.     }
  610.  
  611. /*-----------------------------------------------------------------*/
  612. /*---------------------- PROTECTED METHODS ------------------------*/
  613. /*-----------------------------------------------------------------*/
  614.  
  615.     pascal Boolean ModalFilterProc (DialogPtr theDlg,
  616.                                     EventRecord *theEvent,
  617.                                     short *itemHit)
  618.     /* this class method is used as the modal dialog filter; it */
  619.     /* passes the event it receives on to the window object stored */
  620.     /* in gTheModalWindow */ 
  621.     {
  622.         if (gTheModalWindow)
  623.           return (gTheModalWindow->Do (theEvent));
  624.     }
  625.     
  626. /*-----------------------------------------------------------------*/
  627.  
  628.     void    CPPWindow::Activate (void)
  629.     /* do the necessary bookkeeping to keep track of the window's state */
  630.     /* and pass the message on to all the window's contents */
  631.     {        
  632.         for (long i = 1; i<= GetNumItems(); i++)
  633.           {
  634.               CPPVisualObject    *theObject = (CPPVisualObject *)((*this)[i]);
  635.               if (theObject)
  636.                 theObject->Activate(TRUE);
  637.           }
  638.           
  639.         if (this->theWindow)
  640.           this->WisActive = TRUE;
  641.     }
  642.             
  643. /*-----------------------------------------------------------------*/
  644.  
  645.     void    CPPWindow::Deactivate (void)
  646.     /* do the necessary bookkeeping to keep track of the window's state */
  647.     {
  648.         for (long i = 1; i<= GetNumItems(); i++)
  649.           {
  650.               CPPVisualObject    *theObject = (CPPVisualObject *)((*this)[i]);
  651.               if (theObject)
  652.                 theObject->Activate(FALSE);
  653.           }
  654.  
  655.         if (this->theWindow)
  656.             this->WisActive = FALSE;
  657.     }
  658.  
  659. /*-----------------------------------------------------------------*/
  660.  
  661.     void    CPPWindow::DoUserChangeSize (short newWidth, short newHeight)
  662.     /* instance specific handler for changing the size of the window */
  663.     /* You might use this to move the window's scrollbars, if it has */
  664.     /* any */
  665.     /* SUBCLASS SHOULD OVERRIDE */
  666.     {
  667.     
  668.     }
  669.  
  670. /*-----------------------------------------------------------------*/
  671.  
  672.     void    CPPWindow::DoUserClick (EventRecord *theEvent)
  673.     /* instance specific handler for clicking in the window */
  674.     /* this handler tests each item and passes the click to the */
  675.     /* one where it occurred */
  676.     /* SUBCLASS SHOULD OVERRIDE */
  677.     {
  678.         for (long i = 1; i<= GetNumItems(); i++)
  679.           {
  680.               CPPVisualObject *theObject = (CPPVisualObject *)((*this)[i]);
  681.               if (theObject && theObject->InContent(theEvent->where))
  682.                 {
  683.                     MakeTarget(theObject);
  684.                   if (theObject->DoClick(theEvent))
  685.                     break;
  686.                 }
  687.           }
  688.     }
  689.     
  690. /*-----------------------------------------------------------------*/
  691.  
  692.     void    CPPWindow::DoUserUpdate (void)
  693.     /* instance specific handler for drawing the window's contents */
  694.     /* this handler goes through each item and draws it */
  695.     /* SUBCLASS SHOULD OVERRIDE */
  696.     {
  697.         for (long i = 1; i<= GetNumItems(); i++)
  698.           {
  699.               CPPVisualObject *theObject = (CPPVisualObject *)((*this)[i]);
  700.               if (theObject)
  701.                 theObject->Draw();
  702.           }
  703.     }
  704.  
  705. /*-----------------------------------------------------------------*/
  706.  
  707.     void    CPPWindow::DoUserAutoScroll (void)
  708.     /* This routine provides users with a callback routine while */
  709.     /* handling a click in a window.  It can be called from inside */
  710.     /* and object's 'DoClick' handler to provide scrolling of the */
  711.     /* window the object is in */
  712.     /* SUBCLASS SHOULD OVERRIDE */
  713.     {
  714.     
  715.     }
  716.  
  717. /*-----------------------------------------------------------------*/
  718.  
  719.     void    CPPWindow::DoUserIdle (void)
  720.     /* instance specific handler for idling when the window is */
  721.     /* the frontmost window - hand it to the current target object */
  722.     /* SUBCLASS SHOULD OVERRIDE */
  723.     {
  724.         if (currentTarget)
  725.           currentTarget->DoIdle();
  726.     }
  727.  
  728. /*-----------------------------------------------------------------*/
  729.  
  730.     Boolean    CPPWindow::DoUserKey (EventRecord *theEvent)
  731.     /* instance specific handler for handling a keypress - hand */
  732.     /* it off to the current target object. */
  733.     /* return TRUE if we handled the key, FALSE otherwise */
  734.     /* SUBCLASS SHOULD OVERRIDE */
  735.     {
  736.         if (currentTarget)
  737.           return currentTarget->DoKey(theEvent->message & charCodeMask,
  738.                                         theEvent->modifiers, theEvent->what);
  739.         else
  740.           return FALSE;
  741.     }
  742.  
  743. /*-----------------------------------------------------------------*/
  744. /*----------------------- PRIVATE METHODS -------------------------*/
  745. /*-----------------------------------------------------------------*/
  746.  
  747.     void    CPPWindow::DoDragClick (EventRecord *theEvent)
  748.     /* drag a window around the screen */
  749.     {
  750.         RgnHandle    deskRegion = GetGrayRgn();
  751.         
  752.         if (this->theWindow)
  753.           DragWindow(this->theWindow, theEvent->where, 
  754.                        &((**deskRegion).rgnBBox));
  755.     }
  756.             
  757. /*-----------------------------------------------------------------*/
  758.  
  759.     void    CPPWindow::DoZoomClick (EventRecord *theEvent, short thePart)
  760.     {
  761.         Point    myPt;
  762.         Rect    tempRect;
  763.         
  764.         if (this->theWindow)
  765.           {
  766.               SetPort(this->theWindow);
  767.               myPt = theEvent->where;
  768.               GlobalToLocal(&myPt);
  769.               if (TrackBox(this->theWindow, myPt, thePart))
  770.                 {
  771.                     ZoomWindow (this->theWindow, thePart, TRUE);
  772.                     
  773.                     // erase the contents of the window
  774.                     SetRect (&tempRect, 0, 0, 32000, 32000);
  775.                     EraseRect(&tempRect);
  776.                     InvalRect(&tempRect);
  777.                     
  778.                     // let the user know the window changed size
  779.                     tempRect = this->theWindow->portRect;
  780.                     DoUserChangeSize (tempRect.right - tempRect.left,
  781.                                       tempRect.bottom - tempRect.top);
  782.                     
  783.                 }
  784.           }
  785.     }
  786.         
  787. /*-----------------------------------------------------------------*/
  788.  
  789.     void    CPPWindow::DoGoAwayClick (EventRecord *theEvent)
  790.     {
  791.         if (this->theWindow)
  792.           {
  793.             if (TrackGoAway (this->theWindow, theEvent->where))
  794.               this->Close();
  795.           }
  796.     }
  797.             
  798. /*-----------------------------------------------------------------*/
  799.  
  800.     void    CPPWindow::DoGrowClick (EventRecord *theEvent)
  801.     {
  802.         Point    myPt;
  803.         Rect    tempRect, oldRect;
  804.         long    mResult;
  805.         WStateData    **hWSD;
  806.         
  807.         if (this->theWindow)
  808.           {
  809.               SetPort(this->theWindow);
  810.               myPt = theEvent->where;
  811.               GlobalToLocal(&myPt);
  812.  
  813.             oldRect = this->theWindow->portRect;
  814.  
  815.             // Set the minimum and maximum sizes for the drag
  816.               SetRect (&tempRect, this->minWidth, this->minHeight,
  817.                         this->maxWidth, this->maxHeight);
  818.                         
  819.               // Drag, then change the window size
  820.               mResult = GrowWindow (this->theWindow, theEvent->where, &tempRect);
  821.               SizeWindow (this->theWindow, LoWord(mResult), 
  822.                           HiWord(mResult), TRUE);
  823.               
  824.               // erase the contents of the window
  825.               SetRect (&tempRect, 0, 0, 32000, 32000);
  826.               EraseRect (&tempRect);
  827.               InvalRect (&tempRect);
  828.  
  829.                 //let the user know the window changed size
  830.                 tempRect = this->theWindow->portRect;
  831.                 DoUserChangeSize (tempRect.right - tempRect.left,
  832.                                   tempRect.bottom - tempRect.top);
  833.           }
  834.     }
  835.             
  836. /*-----------------------------------------------------------------*/
  837.  
  838.     void    CPPWindow::DoContentClick (EventRecord *theEvent)
  839.     {
  840.         if (this->theWindow)
  841.           {
  842.               if (!this->WisActive)
  843.                 this->ourManager->ActivateWindowObject(this);
  844.               SetPort(this->theWindow);
  845.               this->DoUserClick (theEvent);
  846.           }
  847.     }
  848.             
  849. /*-----------------------------------------------------------------*/
  850. /*----------------------- PRIVATE METHODS -------------------------*/
  851. /*-----------------------------------------------------------------*/
  852.  
  853.     void    CPPWindow::MakeCPPWindow (CPPWindowManager *theManager,
  854.                                       short windowFont, short windowSize)
  855.     /* the common part of both constructors */
  856.     {
  857.         GrafPtr    savePort;
  858.         
  859.         this->minWidth = 70;
  860.         this->minHeight = 70;
  861.         
  862.         this->currentTarget = NULL;
  863.         // remember which window manager is ours, and add ourself to 
  864.         // its list
  865.         this->ourManager = theManager;
  866.           this->ourManager->DeactivateWindowObject(this->ourManager->FrontWindowObject());
  867.         this->ourManager->StartManagingWindow(this);
  868.           this->WisActive = FALSE;
  869.           this->WisVisible = ((WindowPeek)this->theWindow)->visible;
  870.           this->ourManager->ActivateWindowObject(this);
  871.           SelectWindow (this->theWindow);
  872.           
  873.           // set the font and font size for the window
  874.           GetPort (&savePort);
  875.           SetPort (this->theWindow);
  876.           TextFont (windowFont);
  877.           TextSize (windowSize);
  878.           SetPort (savePort);
  879.           
  880.     }
  881.